package com.heu.blood.storge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heu.blood.common.Constant.ConstantData;
import com.heu.blood.common.enums.BloodStateEnum;
import com.heu.blood.common.enums.OperateStateEnum;
import com.heu.blood.common.utils.GenerateNumberBySnowFlake;
import com.heu.blood.common.utils.PageUtils;
import com.heu.blood.common.utils.Query;
import com.heu.blood.examine.dictenum.TradeTypeEnum;
import com.heu.blood.examine.entity.OperateExamineEntity;
import com.heu.blood.examine.service.OperateExamineService;
import com.heu.blood.globalExceptionHandler.MyException;
import com.heu.blood.match.entity.BloodInformationEntity;
import com.heu.blood.match.service.BloodInformationService;
import com.heu.blood.security.dao.UserDao;
import com.heu.blood.security.entity.UserEntity;
import com.heu.blood.security.exception.UserLoginException;
import com.heu.blood.storge.dao.BloodBackDao;
import com.heu.blood.storge.dictenum.BloodVerifyEnum;
import com.heu.blood.storge.dictenum.OutStorageReasonEnum;
import com.heu.blood.storge.entity.BloodBackEntity;
import com.heu.blood.storge.entity.BloodInStorgeEntity;
import com.heu.blood.storge.entity.BloodOutStorgeEntity;
import com.heu.blood.storge.entity.BloodVerifyStorgeEntity;
import com.heu.blood.storge.exception.BloodBackException;
import com.heu.blood.storge.service.BloodBackService;
import com.heu.blood.storge.service.BloodInStorgeService;
import com.heu.blood.storge.service.BloodOutStorgeService;
import com.heu.blood.storge.service.BloodVerifyStorgeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import static com.heu.blood.common.enums.CommonEnum.IF_SHOW;
import static com.heu.blood.common.enums.CommonEnum.IS_NOT_DELETED;

@Slf4j
@Service("bloodBackService")
public class BloodBackServiceImpl extends ServiceImpl<BloodBackDao, BloodBackEntity> implements BloodBackService {

    @Autowired
    BloodInStorgeService bloodInStorgeService;

    @Autowired
    BloodInformationService bloodInformationService;

    @Autowired
    BloodVerifyStorgeService bloodVerifyStorgeService;

    @Autowired
    BloodOutStorgeService bloodOutStorgeService;

    @Autowired
    UserDao userDao;

    @Autowired
    OperateExamineService operateExamineService;

    @Autowired
    BloodBackDao bloodBackDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        //构造BloodBack对象
        BloodBackEntity bloodBack = new BloodBackEntity();
        //用于接收传递过来的BloodInstorgeEntity参数
        log.info(String.valueOf(params));
        log.info(String.valueOf(params.get("batchNumber")));
        if(Strings.isNotBlank((String) params.get("bloodId"))){
            bloodBack.setBloodId((String) params.get("bloodId"));//添加bloodId
        }
        if (Strings.isNotBlank((String) params.get("extendCode"))){
            bloodBack.setExtendCode((String) params.get("extendCode")); // 添加产品码
        }
        if (Strings.isNotBlank((String) params.get("aboBloodType"))){
            bloodBack.setAboBloodType((String) params.get("aboBloodType")); // 添加aboBloodType
        }
        if (Strings.isNotBlank((String) params.get("rhBloodType"))){
            bloodBack.setRhBloodType((String) params.get("rhBloodType")); // 添加rhBloodType
        }
        if (Strings.isNotBlank((String) params.get("bloodType"))){
            bloodBack.setBloodType((String) params.get("bloodType")); // 添加bloodType
        }
        if (Strings.isNotBlank((String) params.get("bloodBankDeliveryId"))){
            bloodBack.setBloodBankDeliveryId((String) params.get("bloodBankDeliveryId")); // 添加bloodBankDeliveryId 出库编号
        }
        if (Strings.isNotBlank((String) params.get("bloodSource"))){
            bloodBack.setBloodSource((String) params.get("bloodSource")); // 添加bloodSource供血机构
        }

        if (Strings.isNotBlank(String.valueOf(params.get("batchNumber")))){
            log.info("-------------------");
            if(!String.valueOf(params.get("batchNumber")).equals(new String("null"))){
                bloodBack.setBatchNumber(Long.valueOf(String.valueOf(params.get("batchNumber")))); // 添加batchNumber入库批次号
            }
            log.info(String.valueOf(bloodBack.getBatchNumber()));
            log.info("-----------------------------");
        }
        // 时间格式化，解决Date->String 报错
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //前端应该传来一个入库开始日期一个入库结束日期
        String collectTimeStart = (String)params.get("collectTimeStart");
        String collectTimeEnd = (String) params.get("collectTimeEnd");
        String failureTimeStart = (String)params.get("failureTimeStart");
        String failureTimeEnd = (String) params.get("failureTimeEnd");
        Date CollectTimestart = null;//声明一个采集时间date 开始和结束
        Date CollectTimeEnd = null;//声明一个采集时间date 开始和结束
        Date FailureTimestart = null;//声明一个失效时间date 开始和结束
        Date FailureTimeEnd = null;//声明一个失效时间date 开始和结束
        if(Strings.isNotBlank(collectTimeStart) && collectTimeStart!="null"){
            try {
                CollectTimestart = sdf.parse(collectTimeStart);
                log.info("-----------------------------");
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        if(Strings.isNotBlank(collectTimeEnd) && collectTimeEnd!="null"){
            try {
                CollectTimeEnd = sdf.parse(collectTimeEnd);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        if(Strings.isNotBlank(failureTimeStart) && failureTimeStart!="null"){
            try {
                FailureTimestart = sdf.parse(failureTimeStart);
                log.info("-----------------------------");
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        if(Strings.isNotBlank(failureTimeEnd) && failureTimeEnd!="null"){
            try {
                FailureTimeEnd = sdf.parse(failureTimeEnd);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        if (Strings.isNotBlank((String) params.get("bloodBackReason"))){
            bloodBack.setBloodBackReason((String) params.get("bloodBackReason")); // 添加bloodBackReason退血原因
        }
        // 构造条件构造器对象
        LambdaQueryWrapper<BloodBackEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Strings.isNotBlank(bloodBack.getBloodId()), BloodBackEntity::getBloodId,bloodBack.getBloodId())
                .eq(Strings.isNotBlank(bloodBack.getExtendCode()), BloodBackEntity::getExtendCode, bloodBack.getExtendCode())
                .eq(Strings.isNotBlank(bloodBack.getAboBloodType()), BloodBackEntity::getAboBloodType, bloodBack.getAboBloodType())
                .eq(Strings.isNotBlank(bloodBack.getRhBloodType()), BloodBackEntity::getRhBloodType, bloodBack.getRhBloodType())
                .eq(Strings.isNotBlank(bloodBack.getBloodType()), BloodBackEntity::getBloodType, bloodBack.getBloodType())
                .eq(Strings.isNotBlank(bloodBack.getBloodBankDeliveryId()), BloodBackEntity::getBloodBankDeliveryId, bloodBack.getBloodBankDeliveryId())
                .eq(Strings.isNotBlank(bloodBack.getBloodSource()), BloodBackEntity::getBloodSource, bloodBack.getBloodSource())
                .eq(Strings.isNotBlank(String.valueOf(bloodBack.getBatchNumber()))&&String.valueOf(bloodBack.getBatchNumber())!="null", BloodBackEntity::getBatchNumber, bloodBack.getBatchNumber())
                .eq(Strings.isNotBlank(bloodBack.getBloodBackReason()),BloodBackEntity::getBloodBackReason,bloodBack.getBloodBackReason())
                .eq(BloodBackEntity::getIsDeleted,IS_NOT_DELETED.code())
                .eq(BloodBackEntity::getIfShow,IF_SHOW.code())
                .ge(CollectTimestart != null, BloodBackEntity::getCollectTime, CollectTimestart)//采集时间开始
                .le(CollectTimeEnd != null, BloodBackEntity::getCollectTime, CollectTimeEnd)//采集时间结束
                .ge(FailureTimestart != null, BloodBackEntity::getFailureTime, FailureTimestart)//失效时间开始
                .le(FailureTimeEnd != null, BloodBackEntity::getFailureTime, FailureTimeEnd);//失效时间结束
        queryWrapper.orderByDesc(BloodBackEntity::getFailureTime);
        IPage<BloodBackEntity> page = this.page(
                new Query<BloodBackEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Override
    public BloodBackEntity convertBloodInformationToBloodBackEntity(BloodInformationEntity bloodInformationEntity) {
        //将bloodinformation中的属性依次赋值给bloodback
        BloodBackEntity bloodBackEntity = new BloodBackEntity();
        if (bloodInformationEntity.getBloodId() != null){
            bloodBackEntity.setBloodId(bloodInformationEntity.getBloodId());
        }
        if (bloodInformationEntity.getBarcode() != null){
            bloodBackEntity.setBarcode(bloodInformationEntity.getBarcode());
        }
        if (bloodInformationEntity.getExtendCode() != null){
            bloodBackEntity.setExtendCode(bloodInformationEntity.getExtendCode());
        }
        if (bloodInformationEntity.getBloodType() != null){
            bloodBackEntity.setBloodType(bloodInformationEntity.getBloodType());
        }
        if (bloodInformationEntity.getBloodCount() != null){
            bloodBackEntity.setBloodCount(bloodInformationEntity.getBloodCount());
        }
        if (bloodInformationEntity.getAboBloodType() != null){
            bloodBackEntity.setAboBloodType(bloodInformationEntity.getAboBloodType());
        }
        if (bloodInformationEntity.getRhBloodType() != null){
            bloodBackEntity.setRhBloodType(bloodInformationEntity.getRhBloodType());
        }
        if (bloodInformationEntity.getFailureTime() != null){
            bloodBackEntity.setFailureTime(bloodInformationEntity.getFailureTime());
        }
        if (bloodInformationEntity.getCollectTime() != null){
            bloodBackEntity.setCollectTime(bloodInformationEntity.getCollectTime());
        }
        if (bloodInformationEntity.getBloodSource() != null){
            bloodBackEntity.setBloodSource(bloodInformationEntity.getBloodSource());
        }
        if (bloodInformationEntity.getInboundPrice() != null){
            bloodBackEntity.setInboundPrice(bloodInformationEntity.getInboundPrice());
        }
        if (bloodInformationEntity.getBloodLocation() != null){
            bloodBackEntity.setBloodLocation(bloodInformationEntity.getBloodLocation());
        }
        if (bloodInformationEntity.getBloodPrice() != null){
            bloodBackEntity.setBloodPrice(bloodInformationEntity.getBloodPrice());
        }
        if (bloodInformationEntity.getMeasurementUnit() != null){
            bloodBackEntity.setMeasurementUnit(bloodInformationEntity.getMeasurementUnit());
        }
        if (bloodInformationEntity.getBatchNumber() != null){
            bloodBackEntity.setBatchNumber(bloodInformationEntity.getBatchNumber());
        }
        //后面三个入库的时候不一定有
        bloodBackEntity.setBloodDonationCode(bloodInformationEntity.getBloodDonationCode());
        bloodBackEntity.setBloodBankDeliveryId(bloodInformationEntity.getBloodBankDeliveryId());
        bloodBackEntity.setHospitalClassification(bloodInformationEntity.getHospitalClassification());
        return bloodBackEntity;
    }

    @Override
    public void simpleUpdateBloodBackReasonByBloodId(String bloodId, String bloodBackReason) {
        LambdaUpdateWrapper<BloodBackEntity> bloodBackEntityLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        bloodBackEntityLambdaUpdateWrapper.eq(Strings.isNotBlank(bloodId),BloodBackEntity::getBloodId,bloodId);
        bloodBackEntityLambdaUpdateWrapper.set(BloodBackEntity::getBloodBackReason,bloodBackReason);
        this.update(bloodBackEntityLambdaUpdateWrapper);
    }

    @Override
    @Transactional
    public void bloodBackByBloodId(BloodBackEntity bloodBack) {
        // 根据血液id进行退血操作

        // 避免库存中的操作人和退血的操作人搞混淆
        String operatorId = bloodBack.getOperatorId();
        String operatorName = bloodBack.getOperatorName();

        String verifyName = bloodBack.getVerifyName();
        LambdaQueryWrapper<UserEntity> userEntityQuery = new LambdaQueryWrapper<>();
        userEntityQuery.eq(UserEntity::getUserName,verifyName);
        UserEntity userEntity = userDao.selectOne(userEntityQuery);
        if (userEntity == null){
            throw  new MyException(UserLoginException.NO_USER);
        }
        String verifyId = userEntity.getUserId();

        //1.首先查出入库表中存在的数据信息
        LambdaQueryWrapper<BloodInStorgeEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BloodInStorgeEntity::getBloodId, bloodBack.getBloodId());
        BloodInStorgeEntity inStorageEntity = bloodInStorgeService.getOne(queryWrapper);

        //2.之后拷贝数据
        BeanUtils.copyProperties(inStorageEntity,bloodBack);
        bloodBack.setOperatorId(operatorId);
        bloodBack.setOperatorName(operatorName);
        LambdaQueryWrapper<BloodBackEntity> bloodBackQueryWrapper = new LambdaQueryWrapper<>();
        bloodBackQueryWrapper.eq(BloodBackEntity::getBloodId,bloodBack.getBloodId());
        BloodBackEntity backResult = this.getOne(bloodBackQueryWrapper);
        if(backResult != null){
            throw new MyException(BloodBackException.DUPLICATE_BLOODID);
        }

//        String dateStr = new java.text.SimpleDateFormat("yyyyMMdd").format(new Date());
//        String backPrefix = ConstantData.BLOOD_BACK_NO_WORK_ID;
//
//        QueryWrapper<BloodBackEntity> backWrapper = new QueryWrapper<>();
//        backWrapper.likeRight("blood_return_id", backPrefix + dateStr);  // 只查当天数据
//        backWrapper.orderByDesc("blood_return_id");
//        backWrapper.last("limit 1");
//        BloodBackEntity maxBackEntity = this.getBaseMapper().selectOne(backWrapper);
//
//        int nextSeq = 1;
//        if (maxBackEntity != null && maxBackEntity.getBloodId() != null) {
//            String maxNo = maxBackEntity.getBloodId();
//            // 前缀 + 日期 + 4位序列
//            if (maxNo.length() >= (backPrefix.length() + 12)) {
//                String seqStr = maxNo.substring(backPrefix.length() + 8, backPrefix.length() + 12);
//                nextSeq = Integer.parseInt(seqStr) + 1;
//            }
//        }
//        String seqStr = String.format("%04d", nextSeq);
//        String bloodReturnId = backPrefix + dateStr + seqStr;
//        bloodBack.setBloodReturnId(bloodReturnId);
//
//
//        //3.之后将这个退血数据塞进去
          bloodBack.setVerifyId(verifyId);
//        bloodBack.setGmtCreate(new Date());
//        bloodBack.setGmtModified(new Date());
//        this.save(bloodBack);
        //4.更新血液验证表中数据为失败
//        LambdaUpdateWrapper<BloodVerifyStorgeEntity> verifyUpdateWrapper = new LambdaUpdateWrapper<>();
//        verifyUpdateWrapper.set(BloodVerifyStorgeEntity::getVerifyResult, BloodVerifyEnum.VERIFY_FAIL.code());
//        verifyUpdateWrapper.eq(BloodVerifyStorgeEntity::getBloodId,bloodBack.getBloodId());
//        bloodVerifyStorgeService.update(verifyUpdateWrapper);
        //5.更新血液信息表中
//        LambdaUpdateWrapper<BloodInformationEntity> informationUpdateWrapper = new LambdaUpdateWrapper<>();
//        informationUpdateWrapper.set(BloodInformationEntity::getBloodState, BloodStateEnum.RETURN_TO_BLOODSTATION.code());
//        informationUpdateWrapper.eq(BloodInformationEntity::getBloodId,bloodBack.getBloodId());
//        bloodInformationService.update(informationUpdateWrapper);
//        //6.更新库存表中数据为退回血站
//        LambdaUpdateWrapper<BloodInStorgeEntity> storageUpdateWrapper = new LambdaUpdateWrapper<>();
//        storageUpdateWrapper.set(BloodInStorgeEntity::getBloodState, BloodStateEnum.RETURN_TO_BLOODSTATION.code());
//        storageUpdateWrapper.eq(BloodInStorgeEntity::getBloodId,bloodBack.getBloodId());
//        bloodInStorgeService.update(storageUpdateWrapper);
//
//        //7.同步更新到出库表中
//        BloodOutStorgeEntity outStorgeEntity = new BloodOutStorgeEntity();
//        BeanUtils.copyProperties(bloodBack,outStorgeEntity);
//        GenerateNumberBySnowFlake generateNumberBySnowFlake = new GenerateNumberBySnowFlake(ConstantData.BLOOD_OUT_STORAGE_NO_WORK_ID, ConstantData.BLOOD_OUT_STORAGE_NO_PREFIX);
//        String outStorageId = generateNumberBySnowFlake.genNumberByflag();
//        outStorgeEntity.setOutStorgeTime(new Date());
//        outStorgeEntity.setBloodBankDeliveryId(outStorageId);
//        outStorgeEntity.setOutStorgeReason(OutStorageReasonEnum.WITH_DRAW_BLOOD.code());
//        bloodOutStorgeService.save(outStorgeEntity);


        OperateExamineEntity examine = new OperateExamineEntity();
        // tradeId 建议使用退血主键；若需血液ID，请改成 bloodBack.getBloodId()
        examine.setTradeId(bloodBack.getBloodId());
        examine.setTradeType(TradeTypeEnum.BLOOD_BACK.code());
        // 单节点，无下一节点
        examine.setExamineIndex(1);

        examine.setOperatorId(verifyId);
        examine.setOperatorName(verifyName);

        examine.setOperateState(OperateStateEnum.WAIT.code());

        examine.setBackReason(bloodBack.getBloodBackReason());
        operateExamineService.save(examine);
    }

    @Override
    public BloodBackEntity selectByBloodId(String tradeId) {
        LambdaQueryWrapper<BloodBackEntity> bloodBackEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        bloodBackEntityLambdaQueryWrapper.eq(BloodBackEntity::getBloodId,tradeId);
        BloodBackEntity bloodBackEntity = bloodBackDao.selectOne(bloodBackEntityLambdaQueryWrapper);
        return bloodBackEntity;
    }


}